﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include <string>
#include "GcmpModelInterface.h"
#include "IDbObject.h"

namespace gcmp
{
    class IElement;
    class IModelView;

    /// \brief Element可见性过滤器
    class GCMP_MODEL_INTERFACE_EXPORT IElementVisibilityFilter : public IDbObject
    {
        DEFINE_CAST_DERIVED(gcmp::IElementVisibilityFilter, gcmp::IDbObject)

    public:
        /// \brief 获取过滤器名字
        /// \return 过滤器的名字，不能为空，且不能与已有的过滤器同名
        virtual const std::wstring& GetUniqueName() const = 0; 
        GCMP_OBSOLETE_API(2021 / 10 / 01, IElementVisibilityFilter::GetUniqueName()) virtual std::wstring GetName() const = 0;
        
        

        /// \brief 确定Element在视图中的可见性
        /// \param pModelView Element所在视图
        /// \param pElement 需要确定可见性的Element
        /// \return true-可见，false-不可见
        virtual bool IsElementVisible(const IModelView* pModelView, const IElement* pElement) const = 0;

        /// \brief 确定Element在视图中是否可编辑
        /// \param pModelView Element所在视图
        /// \param pElement 需要确定可编辑性的Element
        /// \return true-可编辑，false-不可编辑
        virtual bool IsElementEditable(const IModelView* pModelView, const IElement* pElement) const = 0;

        /// \brief 启用过滤器
        /// \param enable 是否启用
        virtual void EnableFilter(bool enable) = 0;

        /// \brief 过滤器是否启用
        /// \return true-已启用，false-未启用
        virtual bool IsFilterEnabled() const = 0;

        /// \brief 过滤器中判断是否可编辑是否生效
        ///
        /// 只有在过滤器启用时才生效,默认只有在注册了视图平面过滤器且忽略视图深度方向的平面时启用
        /// \param pModelView Element所在视图
        /// \param pElement 需要确定可编辑性的Element
        /// \return true-已启用，false-未启用
        virtual bool IsEditableEnabled(const IModelView* pModelView) const;

        /// \brief 设置该行为所属Element
        /// \param pOwnerElement 所属Element
        /// \return bool
        virtual bool SetOwnerElement(IElement* pOwnerElement);

        /// \brief 获得该外部对象所属Element
        /// \return const IElement* 所属Element
        virtual const IElement* GetOwnerElement() const;

        /// \brief 获得该外部对象所属Element
        /// \return IElement* 所属Element
        virtual IElement* GetOwnerElement();
    };

    /// \brief 某个ModelView里无效Element的过滤器，需要在创建这些Element前就把Filter设置到ModelView上
    /// Filter的生命周期由外部管理
    /// 函数1只在增量刷新时生效，函数2只在uiview时生效
    /// 注意，不要把Invalid状态和modelView状态关联起来，一个element在一个modelView里要么始终valid，要么始终invalid
    /// 如果把Invalid状态和modelView状态关联起来，可能导致增量刷新结果错误
    class GCMP_MODEL_INTERFACE_EXPORT IElementInvalidFilter : public WeakReferenceable
    {
    public:
        /// \brief 创建Element时使用它进行判断，外部可以考虑通过bool标记(性能好)和临时hash(Invalid和Valid混在一个事务提交时要采用临时hash)来判断
        /// \param pModelView Element所在视图
        /// \param elemId Element的id
        /// \return true-Element在该视图无效，false-Element在该视图有效
        virtual bool IsElementInvalid(const IModelView *pModelView, const ElementId &elemId) const = 0;
        /// \brief 创建视图时使用它进行判断，因为视图创建是直接从doc获取全部Element，外部需要维护一个InvalidElementID的hash
        /// \param pModelView Element所在视图
        /// \param elemId Element的id
        /// \return true-Element在该视图无效，false-Element在该视图有效
        virtual bool IsElementInvalidWhenShow(const IModelView *pModelView, const ElementId &elemId) const = 0;
    };
}


